package com.hk.core.autoconfigure.data.mongodb;

import com.hk.commons.util.SnowflakeUtils;
import com.hk.core.data.mongodb.domain.AbstractSnowflakeIdPersistable;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.mongodb.config.EnableReactiveMongoAuditing;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertCallback;
import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeConvertCallback;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
import reactor.core.publisher.Mono;

/**
 * MongoDbAutoConfiguration
 *
 * @author Kevin
 */
@AutoConfiguration
@ConditionalOnClass(value = {MongoTemplate.class})
public class MongoDbAutoConfiguration {

    /**
     * servlet 配置
     */
    @Configuration
    @EnableMongoAuditing
    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
    @EnableMongoRepositories(basePackages = {"com.hk.**.repository.mongodb"})
    static class MongoDBCallbackConfiguration {

        /**
         * 保存时，如果没有设置id，则设置一个
         */
        @Bean
        @Order(value = 1)
        public BeforeConvertCallback<AbstractSnowflakeIdPersistable> mongoDbSnowflakeIdBeforeSaveCallback() {
            return (entity, collection) -> {
                if (entity.isNew()) {
                    entity.setId(SnowflakeUtils.getIdGenerator().generate());
                }
                return entity;
            };
        }
    }

    /**
     * reactive 配置
     */
    @Configuration
    @EnableReactiveMongoAuditing
    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
    @EnableReactiveMongoRepositories(basePackages = {"com.hk.**.repository.mongodb"})
    static class ReactiveMongoDBCallbackConfiguration {

        /**
         * 保存时，如果没有设置id，则设置一个
         */
        @Bean
        @Order(value = 1)
        public ReactiveBeforeConvertCallback<AbstractSnowflakeIdPersistable> mongoDbSnowflakeIdReactiveBeforeSaveCallback() {
            return (entity, collection) -> {
                if (entity.isNew()) {
                    entity.setId(SnowflakeUtils.getIdGenerator().generate());
                }
                return Mono.just(entity);
            };
        }
    }

}
